﻿namespace Blaze.Editor.CLI
{
    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;

    /// <summary>
    /// 提供TortoiseProc命令的调用接口。
    /// </summary>
    public static class TortoiseProc
    {
        /// <summary>
        /// 获取一个值，表示TortoiseProc是否可用。
        /// </summary>
        public static bool IsAvailable
        {
            get { return mBinPath != null; }
        }

        static TortoiseProc()
        {
#if UNITY_EDITOR_WIN
            try
            {
                var query = from path in Environment.GetEnvironmentVariable("Path").Split(';')
                    let target = Path.Combine(path, "TortoiseProc.exe")
                    where File.Exists(target)
                    select target;
                mBinPath = query.FirstOrDefault();
            }
            catch
            {
                mBinPath = null;
            }
#else
            mBinPath = null;
#endif
        }

        /// <summary>
        /// 从指定的仓库检出工作副本。
        /// </summary>
        /// <param name="url">仓库路径，如https://20.0.0.245/svn/UnityDMJ/trunk</param>
        /// <param name="path">目标路径，如C:\work\UnityDMJ</param>
        public static void Checkout(string url, string path)
        {
            if (!IsAvailable)
            {
                Svn.Checkout(url, path);
                return;
            }

            var process = new Process
            {
                StartInfo =
                {
                    Arguments = string.Format("/command:checkout /url:{0} /path:\"{1}\" /closeonend:3", url, path),
                    FileName = mBinPath,
                    UseShellExecute = false,
                    CreateNoWindow = false,
                    RedirectStandardOutput = false,
                    RedirectStandardError = false
                }
            };
            if (!process.Start())
                throw new ApplicationException("TortoiseProc checkout failed");
            process.WaitForExit();
            var exitCode = process.ExitCode;
            if (exitCode != 0)
                throw new ApplicationException("TortoiseProc checkout failed -> exit code=" + exitCode);
        }

        /// <summary>
        /// 还原指定的工作副本。
        /// </summary>
        /// <param name="path">工作副本完整路径</param>
        public static void Revert(string path)
        {
            if (!IsAvailable)
            {
                Svn.Revert(path);
                return;
            }

            var process = new Process
            {
                StartInfo =
                {
                    Arguments = string.Format("/command:revert /path:\"{0}\" /closeonend:4", path),
                    FileName = mBinPath,
                    UseShellExecute = false,
                    CreateNoWindow = false,
                    RedirectStandardOutput = false,
                    RedirectStandardError = false
                }
            };
            if (!process.Start())
                throw new ApplicationException("TortoiseProc revert failed -> " + path);
            process.WaitForExit();
            var exitCode = process.ExitCode;
            if (exitCode != 0)
                throw new ApplicationException("TortoiseProc revert failed -> exit code=" + exitCode);
        }

        /// <summary>
        /// 更新指定的工作副本。
        /// </summary>
        /// <param name="path">工作副本完整路径</param>
        public static void Update(string path)
        {
            if (!IsAvailable)
            {
                Svn.Update(path);
                return;
            }

            var process = new Process
            {
                StartInfo =
                {
                    Arguments = string.Format("/command:update /path:\"{0}\" /closeonend:3", path),
                    FileName = mBinPath,
                    UseShellExecute = false,
                    CreateNoWindow = false,
                    RedirectStandardOutput = false,
                    RedirectStandardError = false
                }
            };
            if (!process.Start())
                throw new ApplicationException("TortoiseProc update failed -> " + path);
            process.WaitForExit();
            var exitCode = process.ExitCode;
            if (exitCode != 0)
                throw new ApplicationException("TortoiseProc update failed -> exit code=" + exitCode);
        }

        private static readonly string mBinPath;
    }
}